package com.github.uniapp_tx_video_call_plugin;

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.SystemClock;
import android.support.v4.app.ActivityCompat;
import android.util.Log;

import com.alibaba.fastjson.JSONObject;
import com.blankj.utilcode.util.ServiceUtils;
import com.taobao.weex.annotation.JSMethod;
import com.taobao.weex.bridge.JSCallback;
import com.taobao.weex.common.WXModule;
import com.tencent.liteav.CallService;
import com.tencent.liteav.demo.trtcvoiceroom.VoiceRoomMainActivity;
import com.tencent.liteav.demo.trtcvoiceroom.model.VoiceRoomConfig;
import com.tencent.liteav.login.ProfileManager;
import com.tencent.liteav.login.UserModel;
import com.tencent.liteav.meeting.model.impl.TRTCMeetingImpl;
import com.tencent.liteav.meeting.ui.MeetingMainActivity;
import com.tencent.liteav.trtcaudiocalldemo.model.TRTCAudioCallImpl;
import com.tencent.liteav.trtcaudiocalldemo.model.TRTCAudioCallListener;
import com.tencent.liteav.trtcaudiocalldemo.ui.TRTCAudioCallActivity;
import com.tencent.liteav.trtcvideocalldemo.model.TRTCVideoCallImpl;
import com.tencent.liteav.trtcvideocalldemo.model.TRTCVideoCallListener;
import com.tencent.liteav.trtcvideocalldemo.ui.TRTCVideoCallActivity;
import com.tencent.trtc.TRTCCloudDef;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class TxCallModel extends WXModule {
    public static final int callType_voice = 1;
    public static final int callType_video = 2;
    public static final int callType_voice_meeting = 3;
    public static final int callType_video_meeting = 4;
    private  ArrayList<UserModel> targets;
    private int callType = 0;
    private int roomId;
    @JSMethod(uiThread = true)
    public void config(JSONObject config, final JSCallback callback){

        if(TxVideoConfig.IMloginState == MyEventObject.EVENT_IM_LOGINED){
            JSONObject data = new JSONObject();
            data.put("code", TxVideoConfig.IMloginState);
            callback.invoke(data);
            Log.e("TxCallModel","login callBack1");
            return;
        }

        Log.e("TxCallModel",config.toJSONString());

        String myUserID = config.getString("userId");

        String mySign = config.getString("userSig");

        String myName = config.getString("nickName");

        int appID = config.getIntValue("appid");

        TxVideoConfig.SDKAPPID = appID;

        UserModel myModel = new UserModel();

        myModel.userSig = mySign;

        myModel.userName = myName;

        myModel.userId = myUserID;

        boolean useRandom = config.getBooleanValue("useDefaultRandomAvatar");

        TxVideoConfig.useDefaultRandomAvatar = useRandom;

        if(useRandom){
            myModel.userAvatar = ProfileManager.getInstance().getAvatarUrl(myModel.userId);
        }
        else{
            myModel.userAvatar = config.getString("userAvatar");
        }

        ProfileManager.getInstance().login(myModel);

        if (ProfileManager.getInstance().isLogin()
                && !ServiceUtils.isServiceRunning(CallService.class)) {
            Intent intent = new Intent(mWXSDKInstance.getContext(), CallService.class);
            mWXSDKInstance.getContext().startService(intent);
        }

        new Thread(new Runnable() {
            @Override
            public void run() {
                while ( TxVideoConfig.IMloginState == MyEventObject.EVENT_IM_IDLE){
                    SystemClock.sleep(20);
                }
                if(callback!=null){
                    JSONObject data = new JSONObject();
                    data.put("code", TxVideoConfig.IMloginState);
                    callback.invoke(data);
                    Log.e("TxCallModel","login callBack");
                }
            }
        }).start();

    }

    @JSMethod
    public void closeCall(){
        Log.e("TxCallModel","closeCall");
        TRTCAudioCallImpl.sharedInstance(mWXSDKInstance.getContext()).hangup();
    }

    private  JSCallback  jsCallRef;

    @JSMethod
    public void startCall(JSONObject config,JSCallback callback){
        lastcode = 0;

        Log.e("TxCallModel",config.toJSONString());

        if(!ProfileManager.getInstance().isLogin()){
            setCallBack(callback,Call_State_No_Login,"未登录");
            return;
        }


        JSONObject target = config.getJSONObject("targetInfo");

        String  type = config.getString("callType");

        roomId = config.getIntValue("roomId");

        String  mode = config.getString("mode"); //类型


        //默认是通话模式
        if(mode==null || "".equals(mode)){
            mode = "call";
        }
        else{
          if(roomId==0){
             // ToastUtils.showShort("会议模式,必须指定会议ID");
              if(callback!=null){
                  setCallBack(callback,Call_State_No_RoomID,"未提供会议ID");
              }
              return;
          }
        }

        //默认是语音
        if(type==null || "".equals(type)){
            type = "audio";
        }




        jsCallRef = callback;


        if(mode.toLowerCase().equals("call")){

            UserModel userModel = new UserModel();

            userModel.userId = target.getString("userId");



            userModel.userName = target.getString("nickName");


            if(TxVideoConfig.useDefaultRandomAvatar){
                userModel.userAvatar = ProfileManager.getInstance().getAvatarUrl(userModel.userId);
            }
            else{
                userModel.userAvatar = config.getString("userAvatar");
            }


            targets = new ArrayList<>();

            targets.add(userModel);
            if(type.toLowerCase().equals("audio")){
                callType = callType_voice;


            }
            else{
                callType = callType_video;

            }
        }
        else{
            if(type.toLowerCase().equals("audio")){
                callType = callType_voice_meeting;

            }
            else{ //视频视屏
                callType = callType_video_meeting;
            }
        }

        if(ActivityCompat.checkSelfPermission(mWXSDKInstance.getContext(),Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED){
            ActivityCompat.requestPermissions((Activity) mWXSDKInstance.getContext(),new String[]{
                    Manifest.permission.RECORD_AUDIO,
                    Manifest.permission.CAMERA
            },101);
            return;
        }

        this.doCall();
    }


    private void doCall(){
        switch (callType){
            case callType_voice:
                TRTCAudioCallImpl.sharedInstance(mWXSDKInstance.getContext()).addListener(audioCallListener);
                //语音聊天
                TRTCAudioCallActivity.startCallSomeone(mWXSDKInstance.getContext(),targets);
                break;
            case callType_video:
                TRTCVideoCallImpl.sharedInstance(mWXSDKInstance.getContext()).addListener(videoCallListener);
                TRTCVideoCallActivity.startCallSomeone(mWXSDKInstance.getContext(),targets);
                break;
            case callType_voice_meeting:
                UserModel currentuser = ProfileManager.getInstance().getUserModel();
                final Intent intent = new Intent(mWXSDKInstance.getContext(), VoiceRoomMainActivity.class);
                VoiceRoomConfig config = new VoiceRoomConfig();
                config.roomId = roomId;
                config.userId = currentuser.userId;
                config.sdkAppId = TxVideoConfig.SDKAPPID;
                config.userSig = TxVideoConfig.userSig;
                config.role = TRTCCloudDef.TRTCRoleAnchor;
                config.audioQuality = TRTCCloudDef.TRTC_AUDIO_QUALITY_SPEECH;
                intent.putExtra(VoiceRoomConfig.DATA, config);
                if(mWXSDKInstance.getContext() instanceof Activity){
                    ( (Activity)(mWXSDKInstance.getContext())).startActivityForResult(intent,0);
                }
                else{
                    mWXSDKInstance.getContext().startActivity(intent);
                }
                break;
            case callType_video_meeting:
                currentuser = ProfileManager.getInstance().getUserModel();

                MeetingMainActivity.enterRoom(mWXSDKInstance.getContext(), roomId, currentuser.userId, currentuser.userName, currentuser.userAvatar, true, true, TRTCCloudDef.TRTC_AUDIO_QUALITY_SPEECH);

                break;
        }
    }


    TRTCVideoCallListener videoCallListener = new TRTCVideoCallListener() {
        @Override
        public void onError(int i, String s) {
            setCallBack(jsCallRef,i,s);
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    TRTCVideoCallImpl.sharedInstance(mWXSDKInstance.getContext()).removeListener(videoCallListener);
                }
            },10);
        }

        @Override
        public void onInvited(String s, List<String> list, boolean b, int i) {

        }

        @Override
        public void onGroupCallInviteeListUpdate(List<String> list) {

        }

        @Override
        public void onUserEnter(String s) {

        }

        @Override
        public void onUserLeave(String s) {

        }

        @Override
        public void onReject(String s) {
            new Handler().post(new Runnable() {
                @Override
                public void run() {
                    TRTCVideoCallImpl.sharedInstance(mWXSDKInstance.getContext()).removeListener(videoCallListener);
                }
            });
            setCallBack(jsCallRef,Call_State_reject,"被拒绝");
        }

        @Override
        public void onNoResp(String s) {
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    TRTCVideoCallImpl.sharedInstance(mWXSDKInstance.getContext()).removeListener(videoCallListener);
                }
            },10);
            setCallBack(jsCallRef,Call_State_noRep,"无应答");
        }

        @Override
        public void onLineBusy(String s) {
            new Handler().post(new Runnable() {
                @Override
                public void run() {
                    TRTCVideoCallImpl.sharedInstance(mWXSDKInstance.getContext()).removeListener(videoCallListener);
                }
            });
            setCallBack(jsCallRef,Call_State_busy,"对方忙");
        }

        @Override
        public void onCallingCancel() {
            new Handler().post(new Runnable() {
                @Override
                public void run() {
                    TRTCVideoCallImpl.sharedInstance(mWXSDKInstance.getContext()).removeListener(videoCallListener);
                }
            });
            setCallBack(jsCallRef,Call_State_cannel,"对方会话取消");
        }

        @Override
        public void onCallingTimeout() {
            new Handler().post(new Runnable() {
                @Override
                public void run() {
                    TRTCVideoCallImpl.sharedInstance(mWXSDKInstance.getContext()).removeListener(videoCallListener);
                }
            });
            setCallBack(jsCallRef,Call_State_timeout,"会话超时");
        }

        @Override
        public void onCallEnd() {
            setCallBack(jsCallRef,Call_State_callend,"会话结束",true);
            new Handler().post(new Runnable() {
                @Override
                public void run() {
                    TRTCVideoCallImpl.sharedInstance(mWXSDKInstance.getContext()).removeListener(videoCallListener);
                }
            });
        }
        @Override
        public void onUserVideoAvailable(String s, boolean b) {

        }

        @Override
        public void onUserAudioAvailable(String s, boolean b) {

        }

        @Override
        public void onUserVoiceVolume(Map<String, Integer> map) {

        }
    };


    TRTCAudioCallListener  audioCallListener = new TRTCAudioCallListener() {
        @Override
        public void onError(int i, String s) {
            setCallBack(jsCallRef,i,s);
        }

        @Override
        public void onInvited(String s, List<String> list, boolean b, int i) {

        }

        @Override
        public void onGroupCallInviteeListUpdate(List<String> list) {

        }

        @Override
        public void onUserEnter(String s) {

        }

        @Override
        public void onUserLeave(String s) {

        }

        @Override
        public void onReject(String s) {
            new Handler().post(new Runnable() {
                @Override
                public void run() {
                    TRTCAudioCallImpl.sharedInstance(mWXSDKInstance.getContext()).removeListener(audioCallListener);
                }
            });
            setCallBack(jsCallRef,Call_State_reject,"被拒绝");
        }

        @Override
        public void onNoResp(String s) {
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    TRTCAudioCallImpl.sharedInstance(mWXSDKInstance.getContext()).removeListener(audioCallListener);
                }
            },10);
            setCallBack(jsCallRef,Call_State_noRep,"无应答");
        }

        @Override
        public void onLineBusy(String s) {
            new Handler().post(new Runnable() {
                @Override
                public void run() {
                    TRTCAudioCallImpl.sharedInstance(mWXSDKInstance.getContext()).removeListener(audioCallListener);
                }
            });
            setCallBack(jsCallRef,Call_State_busy,"对方忙");
        }

        @Override
        public void onCallingCancel() {
            new Handler().post(new Runnable() {
                @Override
                public void run() {
                    TRTCAudioCallImpl.sharedInstance(mWXSDKInstance.getContext()).removeListener(audioCallListener);
                }
            });
            setCallBack(jsCallRef,Call_State_cannel,"对方会话取消");
        }

        @Override
        public void onCallingTimeout() {
            new Handler().post(new Runnable() {
                @Override
                public void run() {
                    TRTCAudioCallImpl.sharedInstance(mWXSDKInstance.getContext()).removeListener(audioCallListener);
                }
            });
            setCallBack(jsCallRef,Call_State_timeout,"会话超时");
        }

        @Override
        public void onCallEnd() {
            setCallBack(jsCallRef,Call_State_callend,"会话结束",true);
            new Handler().post(new Runnable() {
                @Override
                public void run() {
                    TRTCAudioCallImpl.sharedInstance(mWXSDKInstance.getContext()).removeListener(audioCallListener);
                }
            });
        }

        @Override
        public void onUserAudioAvailable(String s, boolean b) {

        }

        @Override
        public void onUserVoiceVolume(Map<String, Integer> map) {

        }

    };
    private  void setCallBack(JSCallback callback,int code,String message){
        setCallBack(callback,code,message,false);
    }

    private  int lastcode = -1;

    private  void setCallBack(JSCallback callback,int code,String message,boolean setToNull){
        if(lastcode == code){
            return;
        }
        Log.e("TxCallModel","code=>"+code +" message=>"+message);
        if(callback!=null){
            JSONObject data = new JSONObject();
            data.put("code", code);
            data.put("message",message);
            callback.invoke(data);
        }
        if(setToNull){
            jsCallRef = null;
        }
        lastcode = code;
    }


    @Override
    public void onActivityCreate() {
        super.onActivityCreate();
        Log.e("TxCallModel","onActivityCreate");
    }

    @Override
    public void onActivityDestroy() {
        super.onActivityDestroy();
        Log.e("TxCallModel","onActivityDestroy");
    }

    public static final int Call_State_No_Login = -100;
    public static final int Call_State_No_RoomID = -99;
    public static final int Call_State_reject = -98;
    public static final int Call_State_cannel = -97;
    public static final int Call_State_noRep = -96;
    public static final int Call_State_busy = -95;
    public static final int Call_State_timeout = -94;
    public static final int Call_State_callend = -93;

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        new Handler().post(new Runnable() {
            @Override
            public void run() {
                TRTCAudioCallImpl.sharedInstance(mWXSDKInstance.getContext()).removeListener(audioCallListener);
            }
        });
        setCallBack(jsCallRef,Call_State_callend,"会话结束",true);

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        doCall();
    }
}
